import java.util.Deque;
import java.util.LinkedList;
import java.util.Scanner;
class Pos {
    int x;
    int y;
    char val;

    public Pos(int x, int y, char val) {
        this.x = x;
        this.y = y;
        this.val = val;
    }
}
public class Day38 {
    // 计数
    static int count = 0;
    // 定义 4 个方向
    static byte[][] direct = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};

    // 红与黑-计算瓷砖个数
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNextInt()) {
            int row = in.nextInt();
            int col = in.nextInt();
            in.nextLine(); // 吃空格

            // 记录初始位置
            int x = 0;
            int y = 0;
            // 创建矩阵
            char[][] map = new char[row][col];
            for (int i = 0; i < row; i++) {
                String str = in.nextLine();
                for (int j = 0; j < col; j++) {
                    map[i][j] = str.charAt(j);
                    if (str.charAt(j) == '@') {
                        x = i;
                        y = j;
                    }
                }
            }
            // 多组输入，每次初始化为 0
            count = 0;
//            // dfs 深度搜索
//            dfs(map, x, y, row, col);
            // bfs
            bfs(map,x,y,row,col);
            // 输出
            System.out.println(count);
        }
    }

    // 深度优先 dfs 就是如果一条路径能走，就走到底（递归）
    private static void dfs(char[][] map, int x, int y, int row, int col) {
        // 遇到红块直接返回
        if (map[x][y] == '#') {
            return;
        }
        // 计数
        count++;
        // 说明(x, y)位置为黑砖, 将该砖遍历之后，修改其标记
        map[x][y] = '#';

        // 想其他 4 个方向搜索
        for (int i = 0; i < 4; i++) {
            int nx = x + direct[i][0];
            int ny = y + direct[i][1];

            if (nx >= 0 && nx < row && ny < col && ny >= 0) {
                dfs(map, nx, ny, row, col);
            }
        }
    }

    // 广度优先 bfs 就是先将当前结点周围的路径走完
    private static void bfs(char[][] map, int x, int y, int row, int col) {
        // 广度优先一般是使用队列，类似于二叉树层序遍历
        Deque<Pos> queue = new LinkedList<>();
        // 先将当前结点添加到队列，然后依次出队，
        // 再将上下左右符合条件的添加到队列中
        Pos root = new Pos(x,y,map[x][y]);
        queue.offer(root);
        count = 1;
        // 标记为已走过
        map[x][y] = '#';

        while (queue.size() != 0) {
            // 出队
            Pos pos = queue.poll();

            // 将周围符合条件的入队
            for (int i = 0; i < 4; i++) {
                int nx = pos.x + direct[i][0];
                int ny = pos.y + direct[i][1];

                if (nx >= 0 && nx < row && ny < col && ny >= 0 && map[nx][ny] == '.') {
                    queue.offer(new Pos(nx,ny,map[nx][ny]));
                    // 标志为已走过
                    map[nx][ny] = '#';
                    count++;
                }
            }
        }
    }

    public static void main1(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            int n = sc.nextInt();
            int m = sc.nextInt();
            int k = sc.nextInt();

            // 放置蘑菇,map多给一行一列，因为题目的位置是从(1,1)开始
            int[][] map = new int[n + 1][m + 1];
            while (0 != k) {
                int x = sc.nextInt();
                int y = sc.nextInt();
                map[x][y] = 1;
                k--;
            }

            // dp来计算到dp[i][j]位置的概率
            double[][] dp = new double[n + 1][m + 1];
            dp[1][1] = 1.0;

            // 开始走
            // dp[i][j]: dp[i-1][j] 和 dp[i][j+1]的概率之后
            for (int i = 1; i <= n; ++i) {
                for (int j = 1; j <= m; ++j) {
                    // 除过起始位置
                    if (!(i == 1 && j == 1)) {
                        dp[i][j] = dp[i - 1][j] * (j == m ? 1.0 : 0.5) + dp[i][j - 1] *
                                (i == n ? 1.0 : 0.5);
                    }

                    // 如果(i,j)位置有蘑菇，则无法到达
                    if (map[i][j] == 1) {
                        dp[i][j] = 0.0;
                    }
                }
            }

            // 到达(n,m)的概率为：
            System.out.printf("%.2f\n", dp[n][m]);
        }
    }


    // 计算无障碍时，从 （1,1）-（n,m)一共有多少条路线
    private static int getTotal(int n, int m) {
        // 这里使用动态规划
        // dp[i] 表示到当前位置有多少种走法
        // dp[i] = p[i-1][j]+dp[i][j-1]
        int[][] dp = new int[n + 1][m + 1];
        // 初始化，作为辅助状态
        dp[0][1] = 1;
        // 填表
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
            }
        }
        return dp[n][m];
    }

    // 计算不碰到蘑菇的情况下从 （1,1）-（n,m)一共有多少条路线
    private static int getBest(int n, int m, int[][] map) {
        // 这里使用动态规划
        // dp[i] 表示到当前位置有多少种走法
        // if (map[i][j] == 1) dp[i][j] = 0;
        // else dp[i] = p[i-1][j]+dp[i][j-1]
        int[][] dp = new int[n + 1][m + 1];
        // 初始化，作为辅助状态
        dp[0][1] = 1;
        // 填表
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                if (map[i - 1][j - 1] == 1) {
                    dp[i][j] = 0;
                } else {
                    dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
                }
            }
        }
        return dp[n][m];
    }
}
